#include <brpc/channel.h>
#include "../common/channel.hpp"
#include "../common/Etcd.hpp"
#include <functional>
#include <iostream>
#include <unistd.h>
#include <unistd.h>
#include "main.pb.h"

using namespace XKL;

void callback(example::EchoResponse *rsp)
{
    std::cout << "error rsp" << std::endl;
    // std::unique_ptr<example::EchoResponse> ptr(rsp);
    std::cout << "Rpc message : " << rsp->message() << std::endl;
}

int main()
{
    initLogger("stdout", "", 1);
    // 1. 先构造Rpc信道管理对象
    auto sm = std::make_shared<ServiceManager>();
    sm->careServices("/service/echo");
    auto put_cb = std::bind(&ServiceManager::onServiceOnline, sm.get(), std::placeholders::_1, std::placeholders::_2);
    auto del_cb = std::bind(&ServiceManager::onServiceOffline, sm.get(), std::placeholders::_1, std::placeholders::_2);
    // 2. 构造服务发现对象
    Discovery::ptr dclient = std::make_shared<Discovery>("http://127.0.0.1:2379", "/service", put_cb, del_cb);

    while (true)
    {
        // 3. 通过Rpc信道管理对象，获取Echo服务的信道
        auto channel = sm->getChannel("/service/echo");
        if (!channel) 
        {
            sleep(1);
            return -1;  
        }
        // 4. 发起EchoRpc调用
        example::EchoService_Stub stub(channel.get());
        example::EchoRequest req;
        req.set_message("hello world");
        brpc::Controller *cntl = new brpc::Controller;
        example::EchoResponse *rsp = new example::EchoResponse;
        stub.Echo(cntl, &req, rsp, nullptr);
        if (cntl->Failed())
        {
            std::cout << "Rpc Failed " << cntl->ErrorText() << std::endl;
            delete cntl;
            delete rsp;
            sleep(1);
            continue;
        }
        std::cout << "response message: " << rsp->message() << std::endl;
        sleep(1);
    }

    return 0;
}

// int main()
// {
//     brpc::ChannelOptions options;
//     options.connect_timeout_ms = -1;
//     options.timeout_ms = -1;
//     options.max_retry = 3;
//     brpc::Channel channel;
//     channel.Init("127.0.0.1:8080", &options);
//     example::EchoService_Stub stub(&channel);
//     example::EchoRequest* req = new example::EchoRequest;
//     req->set_message("hello world");
//     brpc::Controller* cntl = new brpc::Controller;
//     example::EchoResponse* rsp = new example::EchoResponse;
//     // 要注意后续的异步调用中依旧会使用到cntl所以不可以提前释放，否则造成越界访问
//     auto clusure = google::protobuf::NewCallback(callback, rsp); // 异步调用
//     stub.Echo(cntl, req, rsp, clusure);
//     // stub.Echo(cntl, req, rsp, nullptr);
//     if(cntl->Failed())
//     {
//         std::cout << "Rpc error" << std::endl;
//         return -1;
//     }
//     // std::cout << "response message: " << rsp->message() << std::endl;
//     std::cout << "异步调用成功" << std::endl;
//     // delete cntl;
//     // delete req;
//     // delete rsp; // 注意一下
//     sleep(3);
//     return 0;
// }